home *** CD-ROM | disk | FTP | other *** search
- /*
- File: FWAVCDriver.c
-
- Contains: Driver software for AVC transport control.
-
- Written by: Erik Staats
-
- Copyright: © 1996-1997 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <FW32> 3/18/97 ES Changed driver description version to final.
- <FW31> 3/10/97 ES Fixed problem with inserting the correct number of empty packets
- in a buffer group.
- <FW30> 3/10/97 ES Removed use of kDVFrameRateNumerator/Denominator and used
- kPlayFrameRateNumerator/Denominator.
- <FW29> 3/10/97 ES Changed to remove empty packets to resynchronize after lost
- cycles. Changed to loop over one frame on playback instead of
- three. Changed to play at a settable frame rate (29.97 Hz in
- header) with settable buffer group sizes. Improved memory
- allocation for playback.
- <FW28> 3/3/97 ES Changed to use DCLTimeStamp to resynchronize SYT field when we
- miss cycles.
- <FW27> 2/14/97 ES Added kFWDCLOpDynamicFlag to jump ops we intend to modify.
- <FW26> 1/16/97 ES Added use of DCLUpdateList commands.
- <FW25> 1/1/97 ES Added UpdateDCLList command to record DCL program.
- <FW24> 12/27/96 ES Changed FWAVCTerminate to check if gpFWAVCDriverData is nil.
- <FW23> 12/27/96 ES Changed a bunch of "FWDriver"s to "FWClient"s.
- <FW22> 12/22/96 ES Changed IsochPortAction to IsochPortControl.
- <FW21> 12/5/96 ES Added an ifdef to conditionaly compile a driver with the correct
- driver name or a driver with an alternate driver name.
- <FW20> 10/22/96 ES Changed to generic driver model.
- <FW19> 10/4/96 ES Replaced DCLSetPacketAttributes with DCLSetTagSyncBits.
- <FW18> 9/27/96 ES Changed to use set driver interface calls rather than driver
- interface table.
- <FW17> 9/24/96 GG Added rewind, review, whatchadoing, fastforward, fastplay, slow,
- nextframe, and previousframe, and pause.
- <FW16> 9/16/96 ES Changed FireWire driver interface procs to return command
- acceptance.
- <FW15> 9/4/96 ES Added more deallocation.
- <FW14> 9/3/96 ES Added line to nil out reset notification proc in driver
- interface table.
- <FW13> 8/29/96 ES Changed FWRegisterDriver to take driver interface proc table.
- <FW12> 8/28/96 ES Changed the way trial works in InitIsochPort.
- <FW11> 8/26/96 ES Changed to use new command object interface.
- <FW10> 8/26/96 ES Changed to accurately set SID field in the CIP header. Also,
- changed some constant names.
- <FW9> 8/19/96 ES Changed to use separate stop and start isochronous param blocks
- for handling DV send overruns.
- <FW8> 8/16/96 ES Changed FWAllocateLocalIsochronousPort to take param block. Made
- some other minor modifications.
- <FW7> 8/15/96 ES Made isoch channel and port stuff asynchronous. Added overrun
- handling to DV output.
- <FW6> 8/2/96 ES Updated for more isochronous changes.
- <FW5> 8/1/96 ES Took out unused local variables.
- <FW4> 7/31/96 ES Changed to use new isochronous buffer architecture.
- <FW3> 7/8/96 ES Added dump and 3 frame snap shot loop playing capabilities.
- <FW2> 6/20/96 ES Filled in contains and written by fields.
- <FW1> 6/20/96 ES first checked in
-
- */
-
- #include <Types.h>
- #include <Errors.h>
- #include <Devices.h>
- #include <DriverServices.h>
- #include <FireWire.h>
- #include <AVTransport.h>
- #include <FWAVCDriver.h>
- /*zzz*/
- #include <TextUtils.h>
- #include <stdio.h>
- char debugStr[256];
- /*zzz*/
- #define PLAY 0x0000c375
- #define SLOW 0x0000c335
- #define PLAYBACK 0x0000c348
- #define FASTPLAY 0x0000c33e
- #define PAUSE 0x0000c37d
- #define REVIEW 0x0000c34e
- #define NEXTFRAME 0x0000c330
- #define PREVIOUSFRAME 0x0000c340
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Internal procedure prototypes.
- //
-
- static OSStatus FWAVCInitIsochPort (
- FWClientInitIsochPortParamsPtr
- pInitIsochPortParams,
- UInt32 *pCommandAcceptance);
-
- static OSStatus FWAVCReleaseIsochPort (
- FWClientReleaseIsochPortParamsPtr
- pReleaseIsochPortParams,
- UInt32 *pCommandAcceptance);
-
- static OSStatus FWAVCStartIsochPort (
- FWClientIsochPortControlParamsPtr
- pIsochPortControlParams,
- UInt32 *pCommandAcceptance);
-
- static OSStatus FWAVCStopIsochPort (
- FWClientIsochPortControlParamsPtr
- pIsochPortControlParams,
- UInt32 *pCommandAcceptance);
-
- static OSStatus FWAVCInitialize (
- RegEntryIDPtr pRegEntryID);
-
- static OSStatus FWAVCTerminate (void);
-
- static OSStatus AVTDriverInterface (
- AVTInterfaceParamsPtr pAVTInterfaceParams);
-
- static OSStatus FWAVCPlay (
- AVTPlayParamsPtr pAVTPlayParams);
-
- static OSStatus FWAVCStop (
- AVTStopParamsPtr pAVTStopParams);
-
- static OSStatus FWAVCRewind (
- AVTRewindParamsPtr pAVTRewindParams);
-
- static OSStatus FWAVCReview (
- AVTReviewParamsPtr pAVTReviewParams);
-
- static OSStatus FWAVCFastForward (
- AVTFastForwardParamsPtr pAVTFastForwardParams);
-
- static OSStatus FWAVCFastPlay (
- AVTFastPlayParamsPtr pAVTFastPlayParams);
-
- static OSStatus FWAVCPause (
- AVTPauseParamsPtr pAVTPauseParams);
-
- static OSStatus FWAVCWhatchaDoing (
- AVTWhatchaDoingParamsPtr pAVTWhatchaDoingParams);
-
- static OSStatus FWAVCSlow (
- AVTSlowParamsPtr pAVTSlowParams);
-
- static OSStatus FWAVCNextFrame (
- AVTNextFrameParamsPtr pAVTNextFrameParams);
-
- static OSStatus FWAVCPreviousFrame (
- AVTPreviousFrameParamsPtr pAVTPreviousFrameParams);
-
- static OSStatus FWAVCDump (
- AVTDumpParamsPtr pAVTDumpParams);
-
- static OSStatus FWAVCPlaySnapShot (
- AVTPlaySnapShotParamsPtr pAVTPlaySnapShotParams);
-
- static OSStatus FWAVCStopSnapShot (
- AVTInterfaceParamsPtr pAVTInterfaceParams);
-
- static void FWAVCDVPingPong (
- DCLCommandPtr pDCLCommandPtr);
-
- static void FWAVCHandleDVSend (
- DCLCommandPtr pDCLCommand);
-
- static void FWAVCUpdateDVSendBuffers (
- DCLCommandPtr pDCLCommandPtr);
-
- static void FWAVCHandleDVSendUnderrun (
- DCLCommandPtr pDCLCommandPtr);
-
- static void FWAVCHandleDVSendUnderrunStopIsochronousChannelCompletionProc (
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData);
-
- static void FWAVCClientCommandCompletionProc (
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData);
-
- static FWAVCPlayBufferGroupDataPtr FWAVCAllocatePlayBufferGroup (
- FWAVCDriverDataPtr pFWAVCDriverData);
-
- static void FWAVCDeallocatePlayBufferGroup (
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData);
-
- static OSStatus FWAVCCreatePlayBufferGroupUpdateList (
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData);
-
- static DCLCommandPtr FWAVCAllocateDCLCommand (
- DCLCommandPoolPtr pDCLCommandPool,
- UInt32 dclSize);
-
- static DCLCommandBlockPtr FWAVCAllocateDCLCommandBlock (
- DCLCommandPoolPtr pDCLCommandPool);
-
- static void FWAVCDeallocateDCLCommandBlock (
- DCLCommandBlockPtr pDCLCommandBlock);
-
- static DCLCommandPoolPtr FWAVCAllocateDCLCommandPool (void);
-
- static void FWAVCDeallocateDCLCommandPool (
- DCLCommandPoolPtr pDCLCommandPool);
-
- static UInt32 FWAVCAddCycleTimeToCycleTime (
- UInt32 cycleTime1,
- UInt32 cycleTime2);
-
- static UInt32 FWAVCSubtractCycleTimeFromCycleTime (
- UInt32 cycleTime1,
- UInt32 cycleTime2);
-
- static UInt32 FWAVCConvertFractionalSecondsToCycleTime (
- UInt32 secondsNumerator,
- UInt32 secondsDenominator);
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // The driver descriptor.
- //
-
- DriverDescription TheDriverDescription =
- {
- kTheDescriptionSignature,
- kInitialDriverDescriptor,
- {
- #ifdef FWAVCAlternateDriver
- "\pfwa02d,10000",
- #else
- "\pfwa02d,10001",
- #endif
- 1, 0, finalStage, 1,
- },
- {
- kDriverIsUnderExpertControl,
- "\pFWAVCDriver",
- },
-
- 1,
- kServiceCategoryNdrvDriver,
- kNdrvTypeIsAVTransport,
- 1,0,0,0
- };
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Global driver data.
- //
-
- FWAVCDriverDataPtr gpFWAVCDriverData = nil;
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // DoDriverIO
- //
- // Main entry point.
- //
-
- OSErr DoDriverIO(
- AddressSpaceID addressSpaceID,
- IOCommandID ioCommandID,
- IOCommandContents ioCommandContents,
- IOCommandCode ioCommandCode,
- IOCommandKind ioCommandKind)
- {
- CntrlParamPtr pCntrlParam;
- OSErr err = noErr;
-
- switch (ioCommandCode)
- {
- case kInitializeCommand :
- err = FWAVCInitialize (&ioCommandContents.initialInfo->deviceEntry);
- break;
-
- case kFinalizeCommand :
- err = FWAVCTerminate ();
-
- case kOpenCommand :
- break;
-
- case kCloseCommand :
- break;
-
- case kControlCommand :
- pCntrlParam = (CntrlParamPtr) ioCommandContents.pb;
- if (pCntrlParam->csCode == cscAVTCommand)
- {
- err = AVTDriverInterface
- (*((AVTInterfaceParamsPtr *) &(pCntrlParam->csParam[0])));
- }
- else
- {
- err = controlErr;
- }
- break;
-
- case kStatusCommand :
- err = statusErr;
- break;
-
- default :
- err = paramErr;
- }
-
- // We're complete.
- if (ioCommandKind == kImmediateIOCommandKind)
- return (err);
- else
- return (IOCommandIsComplete (ioCommandID, err));
-
- return (err);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCInitIsochPort
- //
- // This routine initializes an isochronous port for the AVC camera. If
- // the request is for the talking port, this routine sets up the camera's
- // isochronous port. If the request is for the listening port, this routine
- // sets up the local node's isochronous port.
- //
-
- static OSStatus FWAVCInitIsochPort(
- FWClientInitIsochPortParamsPtr
- pInitIsochPortParams,
- UInt32 *pCommandAcceptance)
- {
- FWAVCDriverDataPtr pFWAVCDriverData;
- FWCommandObjectID isochPortCommandObjectID;
- IsochChannelID isochChannelID;
- UInt32 channelNum;
- UInt32 speed;
- Boolean portIsTalker;
- Boolean trial;
- OSStatus status = noErr;
-
- // Get our driver data.
- pFWAVCDriverData = (FWAVCDriverDataPtr)
- pInitIsochPortParams->fwClientInterfaceParams.fwClientSpecificData;
-
- // Get ID for this channel.
- isochChannelID = pInitIsochPortParams->fwClientIsochPortParams.isochChannelID;
-
- // Get speed and channel number.
- speed = pInitIsochPortParams->speed;
- channelNum = pInitIsochPortParams->channelNum;
-
- // Is this request for the talking port?
- portIsTalker = pInitIsochPortParams->fwClientIsochPortParams.portIsTalker;
-
- // Is this a trial?
- trial = pInitIsochPortParams->trial;
-
- // Initialize.
- if (isochChannelID == pFWAVCDriverData->recordIsochChannelID)
- {
- if (portIsTalker)
- {
- // Port is for camera.
- if (!trial)
- {
- // Check params.
- //zzz We only do channel 63.
- if ((speed > kFWSpeed100MBit) || (channelNum != 63))
- status = paramErr;
- }
- else
- {
- // Return supported channel numbers.
- pInitIsochPortParams->supportedChannelNumHi = 0x00000000;
- pInitIsochPortParams->supportedChannelNumLo = 0x00000001;
-
- // Return supported speed.
- if (speed > kFWSpeed100MBit)
- pInitIsochPortParams->speed = kFWSpeed100MBit;
- }
- }
- else
- {
- // Port is for local node.
- if (!trial)
- {
- // Allocate an isoch port ID.
- status = FWAllocateIsochPortID (&(pFWAVCDriverData->isochPortID),
- pFWAVCDriverData->recordDCLProgramID,
- channelNum,
- speed,
- portIsTalker);
-
- // Send an allocate isoch port command to allocate port for listening.
- if (status == noErr)
- {
- // Set up command object.
- isochPortCommandObjectID = pFWAVCDriverData->isochPortCommandObjectID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command.
- status = FWAllocateLocalIsochronousPort (isochPortCommandObjectID);
- }
- }
- else
- {
- // Return supported channel numbers.
- pInitIsochPortParams->supportedChannelNumHi = 0x00000000;
- pInitIsochPortParams->supportedChannelNumLo = 0x00000001;
-
- // Return supported speed.
- if (speed > kFWSpeed100MBit)
- pInitIsochPortParams->speed = kFWSpeed100MBit;
- }
- }
- }
- else
- {
- if (portIsTalker)
- {
- // Port is for local node.
- if (!trial)
- {
- // Allocate an isoch port ID.
- status = FWAllocateIsochPortID (&(pFWAVCDriverData->isochPortID),
- pFWAVCDriverData->playDCLProgramID,
- channelNum,
- speed,
- portIsTalker);
-
- // Send an allocate isoch port command to allocate port for talking.
- if (status == noErr)
- {
- // Set up command object.
- isochPortCommandObjectID = pFWAVCDriverData->isochPortCommandObjectID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command.
- status = FWAllocateLocalIsochronousPort (isochPortCommandObjectID);
- }
- }
- else
- {
- // Return supported channel numbers.
- pInitIsochPortParams->supportedChannelNumHi = 0x00000000;
- pInitIsochPortParams->supportedChannelNumLo = 0x00000001;
-
- // Return supported speed.
- if (speed > kFWSpeed100MBit)
- pInitIsochPortParams->speed = kFWSpeed100MBit;
- }
- }
- else
- {
- // Port is for camera.
- if (!trial)
- {
- // Check params.
- //zzz We only do channel 63.
- if ((speed > kFWSpeed100MBit) || (channelNum != 63))
- status = paramErr;
- }
- else
- {
- // Return supported channel numbers.
- pInitIsochPortParams->supportedChannelNumHi = 0x00000000;
- pInitIsochPortParams->supportedChannelNumLo = 0x00000001;
-
- // Return supported speed.
- if (speed > kFWSpeed100MBit)
- pInitIsochPortParams->speed = kFWSpeed100MBit;
- }
- }
- }
-
- // Complete FireWire client command.
- FWClientCommandIsComplete
- (pInitIsochPortParams->fwClientInterfaceParams.fwClientCommandID, status);
-
- // Return command acceptance.
- //zzz is this the right way? If we've completed the command, we can accept more.
- *pCommandAcceptance = kFWClientCommandAcceptNoMore;
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCReleaseIsochPort
- //
- // This procedure releases resources allocated for the isochronous channel.
- // If the channel is a listener, this routine will release the local
- // isochronous port.
- //
-
- static OSStatus FWAVCReleaseIsochPort(
- FWClientReleaseIsochPortParamsPtr
- pReleaseIsochPortParams,
- UInt32 *pCommandAcceptance)
- {
- FWAVCDriverDataPtr pFWAVCDriverData;
- FWCommandObjectID isochPortCommandObjectID;
- IsochChannelID isochChannelID;
- Boolean portIsTalker;
- OSStatus status = noErr;
-
- // Get our driver data.
- pFWAVCDriverData = (FWAVCDriverDataPtr)
- pReleaseIsochPortParams->fwClientInterfaceParams.fwClientSpecificData;
-
- // Get ID for this channel.
- isochChannelID = pReleaseIsochPortParams->fwClientIsochPortParams.isochChannelID;
-
- // Is this request for the talking port?
- portIsTalker = pReleaseIsochPortParams->fwClientIsochPortParams.portIsTalker;
-
- if (isochChannelID == pFWAVCDriverData->recordIsochChannelID)
- {
- if (!portIsTalker)
- {
- // Set up command object to release port.
- isochPortCommandObjectID = pFWAVCDriverData->isochPortCommandObjectID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command.
- FWReleaseLocalIsochronousPort (isochPortCommandObjectID);
-
- // Deallocate isoch port ID.
- FWDeallocateIsochPortID (pFWAVCDriverData->isochPortID);
- }
- }
- else
- {
- if (portIsTalker)
- {
- // Set up command object to release port.
- isochPortCommandObjectID = pFWAVCDriverData->isochPortCommandObjectID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command.
- FWReleaseLocalIsochronousPort (isochPortCommandObjectID);
-
- // Deallocate isoch port ID.
- FWDeallocateIsochPortID (pFWAVCDriverData->isochPortID);
- }
- }
-
- // Complete FireWire client command.
- FWClientCommandIsComplete
- (pReleaseIsochPortParams->fwClientInterfaceParams.fwClientCommandID, status);
-
- // Return command acceptance.
- //zzz is this the right way? If we've completed the command, we can accept more.
- *pCommandAcceptance = kFWClientCommandAcceptNoMore;
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCStartIsochPort
- //
- // This procedure starts the isochronous channel. If the channel is a
- // talker, this procedure will program the camera to start sending isochronous
- // data. If the channel is a listener, this procedure will start the local
- // isochronous port.
- //
-
- static OSStatus FWAVCStartIsochPort(
- FWClientIsochPortControlParamsPtr
- pIsochPortControlParams,
- UInt32 *pCommandAcceptance)
- {
- FWClientCommandID fwClientCommandID;
- FWAVCDriverDataPtr pFWAVCDriverData;
- FWCommandObjectID isochPortCommandObjectID;
- FWCommandObjectID fcpCommandObjectID;
- UInt32 *pFCPPlayFrame;
- IsochChannelID isochChannelID;
- Boolean portIsTalker;
- Boolean completionIsPending = false;
- OSStatus status = noErr;
-
- // Get our driver data.
- pFWAVCDriverData = (FWAVCDriverDataPtr)
- pIsochPortControlParams->fwClientInterfaceParams.fwClientSpecificData;
-
- // Get ID for this channel.
- isochChannelID = pIsochPortControlParams->fwClientIsochPortParams.isochChannelID;
-
- // Is this request for the talking port?
- portIsTalker = pIsochPortControlParams->fwClientIsochPortParams.portIsTalker;
-
- if (isochChannelID == pFWAVCDriverData->recordIsochChannelID)
- {
- if (portIsTalker)
- {
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = pFWAVCDriverData->asyncFCPCommandObjectID;
- pFCPPlayFrame = pFWAVCDriverData->fcpCommandFrame;
- pFCPPlayFrame[0] = 0x0020C375;
-
- fwClientCommandID =
- pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- 0,
- FWAVCClientCommandCompletionProc,
- (UInt32) fwClientCommandID);
-
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) pFCPPlayFrame,
- 4,
- (Ptr) pFCPPlayFrame,
- 40,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
- completionIsPending = true; //zzz what if above call returns an error?
- }
- else
- {
- // Set up command object to start port.
- isochPortCommandObjectID = pFWAVCDriverData->startIsochPortCommandObjectID;
- fwClientCommandID =
- pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- 0,
- FWAVCClientCommandCompletionProc,
- (UInt32) fwClientCommandID);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command to start port.
- status = FWStartLocalIsochronousPort (isochPortCommandObjectID);
- completionIsPending = true; //zzz what if above call returns an error?
- }
- }
- else
- {
- if (portIsTalker)
- {
- // Set up command object to start port.
- isochPortCommandObjectID = pFWAVCDriverData->startIsochPortCommandObjectID;
- fwClientCommandID =
- pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- 0,
- FWAVCClientCommandCompletionProc,
- (UInt32) fwClientCommandID);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command to start port.
- status = FWStartLocalIsochronousPort (isochPortCommandObjectID);
- completionIsPending = true; //zzz what if above call returns an error?
- }
- else
- {
- //zzz don't do anything with camera yet.
- }
- }
-
- // Complete command if completion is not pending.
- if (!completionIsPending)
- {
- status = FWClientCommandIsComplete
- (pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID,
- status);
- }
-
- // Return command acceptance.
- //zzz is this the right way? If we've completed the command, we can accept more.
- *pCommandAcceptance = kFWClientCommandAcceptNoMore;
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCStopIsochPort
- //
- // This procedure stop the isochronous channel. If the channel is a
- // talker, this procedure will program the camera to stop sending isochronous
- // data. If the channel is a listener, this procedure will stop the local
- // isochronous port.
- //
-
- static OSStatus FWAVCStopIsochPort(
- FWClientIsochPortControlParamsPtr
- pIsochPortControlParams,
- UInt32 *pCommandAcceptance)
- {
- FWClientCommandID fwClientCommandID;
- FWAVCDriverDataPtr pFWAVCDriverData;
- FWCommandObjectID isochPortCommandObjectID;
- FWCommandObjectID fcpCommandObjectID;
- UInt32 *pFCPStopFrame;
- IsochChannelID isochChannelID;
- Boolean portIsTalker;
- Boolean completionIsPending = false;
- OSStatus status = noErr;
-
- // Get our driver data.
- pFWAVCDriverData = (FWAVCDriverDataPtr)
- pIsochPortControlParams->fwClientInterfaceParams.fwClientSpecificData;
-
- // Get ID for this channel.
- isochChannelID = pIsochPortControlParams->fwClientIsochPortParams.isochChannelID;
-
- // Is this request for the talking port?
- portIsTalker = pIsochPortControlParams->fwClientIsochPortParams.portIsTalker;
-
- if (isochChannelID == pFWAVCDriverData->recordIsochChannelID)
- {
- if (portIsTalker)
- {
- // Set up FCP command to tell camera to stop the transport.
- fcpCommandObjectID = pFWAVCDriverData->asyncFCPCommandObjectID;
- pFCPStopFrame = pFWAVCDriverData->fcpCommandFrame;
- pFCPStopFrame[0] = 0x0020C460;
-
- fwClientCommandID =
- pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- 0,
- FWAVCClientCommandCompletionProc,
- (UInt32) fwClientCommandID);
-
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) pFCPStopFrame,
- 4,
- (Ptr) pFCPStopFrame,
- 40,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
- completionIsPending = true; //zzz what if above call returns an error?
- }
- else
- {
- // Set up command object to stop port.
- isochPortCommandObjectID = pFWAVCDriverData->stopIsochPortCommandObjectID;
- fwClientCommandID =
- pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- 0,
- FWAVCClientCommandCompletionProc,
- (UInt32) fwClientCommandID);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command to stop port.
- status = FWStopLocalIsochronousPort (isochPortCommandObjectID);
- completionIsPending = true; //zzz what if above call returns an error?
- }
- }
- else
- {
- if (portIsTalker)
- {
- // Set up command object to stop port.
- isochPortCommandObjectID = pFWAVCDriverData->stopIsochPortCommandObjectID;
- fwClientCommandID =
- pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID;
- FWSetFWCommandParams (isochPortCommandObjectID,
- (FWReferenceID) pFWAVCDriverData->fwDriverID,
- 0,
- FWAVCClientCommandCompletionProc,
- (UInt32) fwClientCommandID);
- FWSetIsochPortCommandIsochPortID (isochPortCommandObjectID,
- pFWAVCDriverData->isochPortID);
-
- // Send command to stop port.
- status = FWStopLocalIsochronousPort (isochPortCommandObjectID);
- completionIsPending = true; //zzz what if above call returns an error?
- }
- else
- {
- //zzz don't do anything with camera yet.
- }
- }
-
- // Complete command if completion is not pending.
- if (!completionIsPending)
- {
- status = FWClientCommandIsComplete
- (pIsochPortControlParams->fwClientInterfaceParams.fwClientCommandID,
- status);
- }
-
- // Return command acceptance.
- //zzz is this the right way? If we've completed the command, we can accept more.
- *pCommandAcceptance = kFWClientCommandAcceptNoMore;
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // AVTDriverInterface
- //
- // Main driver interface.
- //
-
- static OSStatus AVTDriverInterface(
- AVTInterfaceParamsPtr pAVTInterfaceParams)
- {
- UInt32 interfaceSelector;
- OSStatus status = noErr;
-
- // Get some params.
- interfaceSelector = pAVTInterfaceParams->interfaceSelector;
-
- // Main dispatch.
- switch (interfaceSelector)
- {
- case kAVTransportPlay :
-
- status = FWAVCPlay ((AVTPlayParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportStop :
-
- status = FWAVCStop ((AVTStopParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportRewind :
-
- status = FWAVCRewind ((AVTRewindParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportReview :
-
- status = FWAVCReview ((AVTReviewParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportFastForward :
-
- status = FWAVCFastForward ((AVTFastForwardParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportFastPlay :
-
- status = FWAVCFastPlay ((AVTFastPlayParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportWhatchaDoing :
-
- status = FWAVCWhatchaDoing ((AVTWhatchaDoingParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportPause :
-
- status = FWAVCPause ((AVTPauseParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportSlow :
-
- status = FWAVCSlow ((AVTSlowParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportNextFrame :
-
- status = FWAVCNextFrame ((AVTNextFrameParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportPreviousFrame :
-
- status = FWAVCPreviousFrame ((AVTPreviousFrameParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportDump :
-
- status = FWAVCDump ((AVTDumpParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportPlaySnapShot :
-
- status = FWAVCPlaySnapShot ((AVTPlaySnapShotParamsPtr) pAVTInterfaceParams);
- break;
-
- case kAVTransportStopSnapShot :
-
- status = FWAVCStopSnapShot (pAVTInterfaceParams);
- break;
-
- default :
- status = paramErr;
- break;
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCInitialize
- //
- // This routine initializes the FireWire AVC transport control driver. It
- // allocates a private data record and registers with the FireWire family.
- //
-
- static OSStatus FWAVCInitialize(
- RegEntryIDPtr pRegEntryID)
- {
- FWAVCDriverDataPtr pFWAVCDriverData = nil;
- FWDriverID fwDriverID;
- IsochChannelID isochChannelID;
- DCLCommandPtr recordDCLList;
- DCLCommandPtr *recordUpdateDCLList;
- OSStatus status = noErr;
-
- // Allocate our driver data.
- pFWAVCDriverData =
- (FWAVCDriverDataPtr) PoolAllocateResident (sizeof (FWAVCDriverData), true);
- if (pFWAVCDriverData == nil)
- {
- status = memFullErr;
- }
-
- // Register with the FireWire family.
- if (status == noErr)
- {
- status = FWRegisterDriver (pRegEntryID,
- &fwDriverID,
- &(pFWAVCDriverData->csrUnitID),
- (UInt32) pFWAVCDriverData);
-
- if (status == noErr)
- pFWAVCDriverData->fwDriverID = fwDriverID;
- }
-
- // Set initialize isoch port interface proc.
- if (status == noErr)
- {
- status = FWSetFWClientInitIsochPortProc
- ((FWReferenceID) fwDriverID, FWAVCInitIsochPort);
- }
-
- // Set release isoch port interface proc.
- if (status == noErr)
- {
- status = FWSetFWClientReleaseIsochPortProc
- ((FWReferenceID) fwDriverID, FWAVCReleaseIsochPort);
- }
-
- // Set start isoch port interface proc.
- if (status == noErr)
- {
- status = FWSetFWClientStartIsochPortProc
- ((FWReferenceID) fwDriverID, FWAVCStartIsochPort);
- }
-
- // Set stop isoch port interface proc.
- if (status == noErr)
- {
- status = FWSetFWClientStopIsochPortProc
- ((FWReferenceID) fwDriverID, FWAVCStopIsochPort);
- }
-
- // Get reference to local node.
- if (status == noErr)
- {
- status = FWGetLocalFWReferenceIDFromFWReferenceID
- (pFWAVCDriverData->fwDriverID,
- &(pFWAVCDriverData->localFWReferenceID));
- }
-
- // Allocate an isochronous channel to play video data.
- if (status == noErr)
- {
- status = FWAllocateIsochronousChannelID
- (&isochChannelID, true, 30000000, kFWSpeed100MBit);
-
- if (status == noErr)
- pFWAVCDriverData->playIsochChannelID = isochChannelID;
- }
-
- // Add camera as listening client.
- if (status == noErr)
- {
- status = FWAddIsochronousChannelClient
- (pFWAVCDriverData->playIsochChannelID,
- pFWAVCDriverData->fwDriverID,
- (UInt32) pFWAVCDriverData,
- false);
- }
-
- // Add local node as talking client.
- if (status == noErr)
- {
- status = FWAddIsochronousChannelClient
- (pFWAVCDriverData->playIsochChannelID,
- pFWAVCDriverData->fwDriverID,
- (UInt32) pFWAVCDriverData,
- true);
- }
-
- // Allocate an isochronous channel to record video data.
- if (status == noErr)
- {
- status = FWAllocateIsochronousChannelID
- (&isochChannelID, false, 30000000, kFWSpeed100MBit);
-
- if (status == noErr)
- pFWAVCDriverData->recordIsochChannelID = isochChannelID;
- }
-
- // Add camera as talking client.
- if (status == noErr)
- {
- status = FWAddIsochronousChannelClient
- (pFWAVCDriverData->recordIsochChannelID,
- pFWAVCDriverData->fwDriverID,
- (UInt32) pFWAVCDriverData,
- true);
- }
-
- // Add local node as listening client.
- if (status == noErr)
- {
- status = FWAddIsochronousChannelClient
- (pFWAVCDriverData->recordIsochChannelID,
- pFWAVCDriverData->fwDriverID,
- (UInt32) pFWAVCDriverData,
- false);
- }
-
- // Create a DCL program for recording.
- if (status == noErr)
- status = FWCreateDCLProgram (&(pFWAVCDriverData->recordDCLProgramID));
-
- // Create list of DCLs for recording.
- if (status == noErr)
- {
- recordDCLList =
- (DCLCommandPtr) PoolAllocateResident (kRecordDCLProgramSize, false);
-
- if (recordDCLList != nil)
- pFWAVCDriverData->recordDCLList = recordDCLList;
- else
- status = memFullErr;
- }
-
- // Create DCL update list for recording.
- if (status == noErr)
- {
- recordUpdateDCLList = (DCLCommandPtr *)
- PoolAllocateResident (kRecordNumDCLs * sizeof (DCLCommandPtr), false);
-
- if (recordUpdateDCLList != nil)
- pFWAVCDriverData->recordUpdateDCLList = recordUpdateDCLList;
- else
- status = memFullErr;
- }
-
- // Create a DCL program for playing.
- if (status == noErr)
- status = FWCreateDCLProgram (&(pFWAVCDriverData->playDCLProgramID));
-
- // Allocate FireWire command object for sending isoch channel commands
- // synchronously.
- if (status == noErr)
- {
- status = FWAllocateIsochChannelCommandObject
- (&(pFWAVCDriverData->isochChannelCommandObjectID));
- }
-
- // Allocate FireWire command object for sending stop isoch channel commands
- // asynchronously.
- if (status == noErr)
- {
- status = FWAllocateIsochChannelCommandObject
- (&(pFWAVCDriverData->stopIsochChannelCommandObjectID));
- }
-
- // Allocate FireWire command object for sending start isoch channel commands
- // asynchronously.
- if (status == noErr)
- {
- status = FWAllocateIsochChannelCommandObject
- (&(pFWAVCDriverData->startIsochChannelCommandObjectID));
- }
-
- // Allocate FireWire command object for sending isoch port commands
- // synchronously.
- if (status == noErr)
- {
- status = FWAllocateIsochPortCommandObject
- (&(pFWAVCDriverData->isochPortCommandObjectID));
- }
-
- // Allocate FireWire command object for sending stop isoch port commands
- // asynchronously.
- if (status == noErr)
- {
- status = FWAllocateIsochPortCommandObject
- (&(pFWAVCDriverData->stopIsochPortCommandObjectID));
- }
-
- // Allocate FireWire command object for sending start isoch port commands
- // asynchronously.
- if (status == noErr)
- {
- status = FWAllocateIsochPortCommandObject
- (&(pFWAVCDriverData->startIsochPortCommandObjectID));
- }
-
- // Allocate FireWire command object for sending FCP commands synchronously.
- if (status == noErr)
- status = FWAllocateFCPCommandObject (&(pFWAVCDriverData->fcpCommandObjectID));
-
- // Allocate FireWire command object for sending FCP commands asynchronously.
- // With asynchronous commands, we must be careful not to use the command ojbect
- // more than once at a time.
- if (status == noErr)
- status = FWAllocateFCPCommandObject (&(pFWAVCDriverData->asyncFCPCommandObjectID));
-
- // Set the maximum packet payload size for camera.
- if (status == noErr)
- {
- status =
- FWSetMaxPayloadSize ((FWReferenceID) pFWAVCDriverData->fwDriverID,
- 512);
- }
-
- // Save our driver data or clean up on error.
- if (status == noErr)
- {
- gpFWAVCDriverData = pFWAVCDriverData;
- }
- else
- {//zzz should use terminate
- if (pFWAVCDriverData != nil)
- PoolDeallocate ((Ptr) pFWAVCDriverData);
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCTerminate
- //
- // This routine terminates the FireWire AVC transport control driver. It
- // deallocates a private data record and unregisters with the FireWire family.
- //zzz need to do more deallocation.
- //zzz need to stop playing snap shot.
- //
-
- static OSStatus FWAVCTerminate(void)
- {
- OSStatus status = noErr;
-
- if (gpFWAVCDriverData != nil)
- {
- // Unregister with FireWire family.
- if (gpFWAVCDriverData->fwDriverID != kInvalidFWDriverID)
- FWUnregisterDriver (gpFWAVCDriverData->fwDriverID);
-
- // Deallocate FireWire command object for sending FCP commands asynchronously.
- if (gpFWAVCDriverData->asyncFCPCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->asyncFCPCommandObjectID);
-
- // Deallocate FireWire command object for sending FCP commands synchronously.
- if (gpFWAVCDriverData->fcpCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->fcpCommandObjectID);
-
- // Deallocate FireWire command object for sending start isoch port commands
- // asynchronously.
- if (gpFWAVCDriverData->startIsochPortCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->startIsochPortCommandObjectID);
-
- // Deallocate FireWire command object for sending stop isoch port commands
- // asynchronously.
- if (gpFWAVCDriverData->stopIsochPortCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->stopIsochPortCommandObjectID);
-
- // Deallocate FireWire command object for sending isoch port commands
- // synchronously.
- if (gpFWAVCDriverData->isochPortCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->isochPortCommandObjectID);
-
- // Deallocate FireWire command object for sending start isoch channel commands
- // asynchronously.
- if (gpFWAVCDriverData->startIsochChannelCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->startIsochChannelCommandObjectID);
-
- // Deallocate FireWire command object for sending stop isoch channel commands
- // asynchronously.
- if (gpFWAVCDriverData->stopIsochChannelCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->stopIsochChannelCommandObjectID);
-
- // Deallocate FireWire command object for sending isoch channel commands
- // synchronously.
- if (gpFWAVCDriverData->isochChannelCommandObjectID != kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (gpFWAVCDriverData->isochChannelCommandObjectID);
-
- // Deallocate DCL program for playing.
- if (gpFWAVCDriverData->playDCLProgramID != kInvalidDCLProgramID)
- FWDisposeDCLProgram (gpFWAVCDriverData->playDCLProgramID);
-
- // Deallocate DCL update list for recording.
- if (gpFWAVCDriverData->recordUpdateDCLList != nil)
- PoolDeallocate ((Ptr) gpFWAVCDriverData->recordUpdateDCLList);
-
- // Deallocate list of DCLs for recording.
- if (gpFWAVCDriverData->recordDCLList != nil)
- PoolDeallocate ((Ptr) gpFWAVCDriverData->recordDCLList);
-
- // Deallocate DCL program for recording.
- if (gpFWAVCDriverData->recordDCLProgramID != kInvalidDCLProgramID)
- FWDisposeDCLProgram (gpFWAVCDriverData->recordDCLProgramID);
-
- // Deallocate isochronous channel Id for recording video data.
- if (gpFWAVCDriverData->recordIsochChannelID != kInvalidIsochChannelID)
- FWDeallocateIsochronousChannelID (gpFWAVCDriverData->recordIsochChannelID);
-
- // Deallocate isochronous channel Id for playing video data.
- if (gpFWAVCDriverData->playIsochChannelID != kInvalidIsochChannelID)
- FWDeallocateIsochronousChannelID (gpFWAVCDriverData->playIsochChannelID);
-
- // Deallocate our driver data.
- PoolDeallocate ((Ptr) gpFWAVCDriverData);
- gpFWAVCDriverData = nil;
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCPlay
- //
- // This routine starts the camera transport playing.
- //
-
- static OSStatus FWAVCPlay(
- AVTPlayParamsPtr pAVTPlayParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpPlayFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpPlayFrame[0] = 0x0020C375;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpPlayFrame[0]),
- 4,
- (Ptr) &(fcpPlayFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCRewind
- //
- // This routine starts the camera transport Rewinding.
- //
-
- static OSStatus FWAVCRewind(
- AVTRewindParamsPtr pAVTRewindParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpRewindFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpRewindFrame[0] = 0x0020C465;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpRewindFrame[0]),
- 4,
- (Ptr) &(fcpRewindFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCReview
- //
- // This routine starts the camera transport Reviewing.
- //
-
- static OSStatus FWAVCReview(
- AVTReviewParamsPtr pAVTReviewParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpReviewFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpReviewFrame[0] = 0x0020c34e;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpReviewFrame[0]),
- 4,
- (Ptr) &(fcpReviewFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCFastForward
- //
- // This routine starts the camera transport FastForwarding.
- //
-
- static OSStatus FWAVCFastForward(
- AVTFastForwardParamsPtr pAVTFastForwardParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpFastForwardFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpFastForwardFrame[0] = 0x0020C475;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpFastForwardFrame[0]),
- 4,
- (Ptr) &(fcpFastForwardFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCFastPlay
- //
- // This routine starts the camera transport FastPlaying.
- //
-
- static OSStatus FWAVCFastPlay(
- AVTFastPlayParamsPtr pAVTFastPlayParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpFastPlayFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpFastPlayFrame[0] = 0x0020c33e;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpFastPlayFrame[0]),
- 4,
- (Ptr) &(fcpFastPlayFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCPause
- //
- // This routine starts the camera transport Pauseing.
- //
-
- static OSStatus FWAVCPause(
- AVTPauseParamsPtr pAVTPauseParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpPauseFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpPauseFrame[0] = 0x0020c37d;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpPauseFrame[0]),
- 4,
- (Ptr) &(fcpPauseFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCSlow
- //
- // This routine starts the camera transport Slowing.
- //
-
- static OSStatus FWAVCSlow(
- AVTSlowParamsPtr pAVTSlowParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpSlowFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpSlowFrame[0] = 0x0020c335;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpSlowFrame[0]),
- 4,
- (Ptr) &(fcpSlowFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCNextFrame
- //
- // This routine starts the camera transport NextFrameing.
- //
-
- static OSStatus FWAVCNextFrame(
- AVTNextFrameParamsPtr pAVTNextFrameParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpNextFrameFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command to tell camera to start the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpNextFrameFrame[0] = 0x0020c330;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpNextFrameFrame[0]),
- 4,
- (Ptr) &(fcpNextFrameFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCPreviousFrame
- //
- // This routine PreviousFrames the camera transport.
- //
-
- static OSStatus FWAVCPreviousFrame(
- AVTPreviousFrameParamsPtr pAVTPreviousFrameParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpPreviousFrameFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command params to tell camera to PreviousFrame the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpPreviousFrameFrame[0] = 0x0020c340;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpPreviousFrameFrame[0]),
- 4,
- (Ptr) &(fcpPreviousFrameFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCStop
- //
- // This routine stops the camera transport.
- //
-
- static OSStatus FWAVCStop(
- AVTStopParamsPtr pAVTStopParams)
- {
- FWCommandObjectID fcpCommandObjectID;
- UInt32 fcpStopFrame[1];
- OSStatus status = noErr;
-
- // Set up FCP command params to tell camera to stop the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
- fcpStopFrame[0] = 0x0020C460;
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpStopFrame[0]),
- 4,
- (Ptr) &(fcpStopFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
- // Send the FCP command.
- status = FWSendFCPCommand (fcpCommandObjectID);
-
- return (status);
- }
-
-
-
- static OSStatus FWAVCWhatchaDoing(
- AVTWhatchaDoingParamsPtr pAVTWhatchaDoingParams)
- {
- OSStatus status = noErr;
- // FWFCPCommandParams fwFCPCommandParams;
- UInt32 fcpWhatchaDoingFrame[1], temp;
- FWCommandObjectID fcpCommandObjectID;
-
- // Set up FCP command params to tell camera to stop the transport.
- fcpCommandObjectID = gpFWAVCDriverData->fcpCommandObjectID;
-
- // Set up FCP command params to tell camera to start WhatchaDoinging.
- fcpWhatchaDoingFrame[0] = 0x0120d07f;
-
- FWSetFWCommandParams (fcpCommandObjectID,
- (FWReferenceID) gpFWAVCDriverData->fwDriverID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetFCPCommandParams (fcpCommandObjectID,
- (Ptr) &(fcpWhatchaDoingFrame[0]),
- 4,
- (Ptr) &(fcpWhatchaDoingFrame[0]),
- 4,
- 100 * durationMillisecond,
- 8,
- 0,
- nil);
-
-
- status = FWSendFCPCommand (fcpCommandObjectID);
- temp = fcpWhatchaDoingFrame[0];
-
- temp = (temp & 0x0000ffff);
-
- // Figure out what return number means to the user
- if (!status) {
- switch (temp) {
- case PLAY:
- pAVTWhatchaDoingParams->what = kAVTransportPlay;
- break;
- case SLOW:
- pAVTWhatchaDoingParams->what = kAVTransportSlow;
- break;
- case PLAYBACK:
- pAVTWhatchaDoingParams->what = kAVTransportPlayBack;
- break;
- case FASTPLAY:
- pAVTWhatchaDoingParams->what = kAVTransportFastPlay;
- break;
- case REVIEW:
- pAVTWhatchaDoingParams->what = kAVTransportReview;
- break;
- case PAUSE:
- pAVTWhatchaDoingParams->what = kAVTransportPause;
- break;
- default:
- pAVTWhatchaDoingParams->what = 0;
- }
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCDump
- //
- // This routine gets a video dump from the camera.
- //
-
- static OSStatus FWAVCDump(
- AVTDumpParamsPtr pAVTDumpParams)
- {
- FWCommandObjectID isochChannelCommandObjectID;
- FWAVCDVPingPongDataPtr pFWAVCDVPingPongData;
- Ptr pDCLCommand;
- DCLLabelPtr pStartDCLLabel;
- DCLTransferPacketPtr pDCLTransferPacket;
- DCLCallProcPtr pDCLPingPongProc;
- DCLJumpPtr pDCLPingPongLoop;
- DCLUpdateDCLListPtr pDCLUpdateDCLList;
- DCLCommandPtr *updateDCLList,
- *pingPongUpdateDCLList;
- UInt32 updateListSize;
- Ptr pingPongBuffer = nil;
- UInt32 size;
- volatile UInt32 *pBufferOffset;
- UInt32 pingPongNum,
- packetNum;
- OSStatus status = noErr;
-
- // Save pointer to params.
- gpFWAVCDriverData->pAVTDumpParams = pAVTDumpParams;
-
- // Create ping pong buffer.
- //zzz should allocate in initialization routine.
- pingPongBuffer = PoolAllocateResident (kPingPongBufferSize, false);
-
- // Get pointer to start of DCL commands and update list.
- pDCLCommand = (Ptr) gpFWAVCDriverData->recordDCLList;
- updateDCLList = gpFWAVCDriverData->recordUpdateDCLList;
-
- // Create label for start of loop.
- pStartDCLLabel = (DCLLabelPtr) pDCLCommand;
- pDCLCommand += sizeof (DCLLabel);
- pStartDCLLabel->pNextDCLCommand = (DCLCommandPtr) pDCLCommand;
- pStartDCLLabel->opcode = kDCLLabelOp;
-
- // Create 2 ping pong buffer lists of 10 packets each.
- for (pingPongNum = 0; pingPongNum < kNumPingPongs; pingPongNum++)
- {
- // Create ping pong data record and fill it in.
- pFWAVCDVPingPongData = (FWAVCDVPingPongDataPtr)
- PoolAllocateResident (sizeof (FWAVCDVPingPongData), true);
- pFWAVCDVPingPongData->pFWAVCDriverData = gpFWAVCDriverData;
- pFWAVCDVPingPongData->pFirstDCLCommand = (DCLCommandPtr) pDCLCommand;
-
- // Create transfer DCL for each packet.
- pingPongUpdateDCLList = updateDCLList;
- updateListSize = 0;
- for (packetNum = 0; packetNum < kNumPacketsPerPingPong; packetNum++)
- {
- // Receive one packet up to kReceiveDVPacketSize bytes.
- pDCLTransferPacket = (DCLTransferPacketPtr) pDCLCommand;
- pDCLCommand += sizeof (DCLTransferPacket);
- pDCLTransferPacket->pNextDCLCommand = (DCLCommandPtr) pDCLCommand;
- pDCLTransferPacket->opcode = kDCLReceivePacketStartOp;
- pDCLTransferPacket->buffer = pingPongBuffer;
- pDCLTransferPacket->size = kReceiveDVPacketSize;
-
- *updateDCLList++ = (DCLCommandPtr) pDCLTransferPacket;
- updateListSize++;
- pingPongBuffer += kReceiveDVPacketSize;
- }
-
- // Create update DCL list.
- pDCLUpdateDCLList = (DCLUpdateDCLListPtr) pDCLCommand;
- pDCLCommand += sizeof (DCLUpdateDCLList);
- pDCLUpdateDCLList->pNextDCLCommand = (DCLCommandPtr) pDCLCommand;
- pDCLUpdateDCLList->opcode = kDCLUpdateDCLListOp;
- pDCLUpdateDCLList->dclCommandList = pingPongUpdateDCLList;
- pDCLUpdateDCLList->numDCLCommands = updateListSize;
-
- // Call the ping pong proc.
- pDCLPingPongProc = (DCLCallProcPtr) pDCLCommand;
- pDCLCommand += sizeof (DCLCallProc);
- pDCLPingPongProc->pNextDCLCommand = (DCLCommandPtr) pDCLCommand;
- pDCLPingPongProc->opcode = kDCLCallProcOp;
- pDCLPingPongProc->proc = FWAVCDVPingPong;
- pDCLPingPongProc->procData = (UInt32) pFWAVCDVPingPongData;
- }
-
- // Loop to start of ping pong.
- pDCLPingPongLoop = (DCLJumpPtr) pDCLCommand;
- pDCLPingPongLoop->pNextDCLCommand = nil;
- pDCLPingPongLoop->opcode = kDCLJumpOp;
- pDCLPingPongLoop->pJumpDCLLabel = pStartDCLLabel;
-
- // Set start of DCL program.
- if (status == noErr)
- {
- status = FWSetDCLProgramStart (gpFWAVCDriverData->recordDCLProgramID,
- gpFWAVCDriverData->recordDCLList);
- }
-
- // Initialize the isochrounous channel.
- if (status == noErr)
- {
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->recordIsochChannelID);
-
- status = FWInitializeIsochronousChannel (isochChannelCommandObjectID);
- if (status == noErr)
- gpFWAVCDriverData->channelInitialized = true;
- }
-
- // Start the isochronous channel for recording.
- if (status == noErr)
- {
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->recordIsochChannelID);
-
- status = FWStartIsochronousChannel (isochChannelCommandObjectID);
- }
-
- // Wait for buffer to fill.
- if (status == noErr)
- {
- size = pAVTDumpParams->dumpBufferSize;
- pBufferOffset = &(pAVTDumpParams->dumpBufferOffset);
- while ((*pBufferOffset) < size)
- {
- }
- }
-
- // Release isochronous channel.
- if (gpFWAVCDriverData->channelInitialized)
- {
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->recordIsochChannelID);
-
- FWStopIsochronousChannel (isochChannelCommandObjectID);
-
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->recordIsochChannelID);
-
- FWReleaseIsochronousChannel (isochChannelCommandObjectID);
-
- gpFWAVCDriverData->channelInitialized = false;
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCPlaySnapShot
- //
- // This routine plays a snapshot video stream.
- //zzz need error checking.
- //
-
- static OSStatus FWAVCPlaySnapShot(
- AVTPlaySnapShotParamsPtr pAVTPlaySnapShotParams)
- {
- FWCommandObjectID isochChannelCommandObjectID;
- DCLCommandPoolPtr pDCLCommandPool;
- DCLCommandPtr pDCLCommand;
- DCLCommandPtr pFirstBufferGroupDCLCommand;
- DCLLabelPtr pUnderrunDCLLabel,
- pLoopDCLLabel,
- pBufferGroupDCLLabel,
- pDCLLabel;
- DCLTransferPacketPtr pDCLTransferPacket;
- DCLCallProcPtr pDCLCallProc;
- DCLSetTagSyncBitsPtr pDCLSetTagSyncBits;
- DCLJumpPtr pDCLJump,
- pBufferGroupDCLJump;
- DCLLabelPtr pBufferGroupSkipEmptyPacketDCLLabel;
- DCLUpdateDCLListPtr pDCLUpdateDCLList;
- DCLTimeStampPtr pDCLTimeStamp;
-
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData;
- UInt32 matchValue[2] = { 0x00780000, 0x80000000 },
- matchMask[2] = { 0xF0FFFF00, 0xFFFF0000 },
- matchIndex;
- UInt32 *pBuffer,
- *pCompactBuffer,
- bufferValue;
- UInt32 *pTransmitBuffer;
- UInt32 snapShotBufferSize,
- goodSnapShotBufferSize;
- UInt32 i,
- bufferGroupNum,
- dataPacketNum,
- numPackets;
- UInt32 numEmptyPacketsPerPlayBufferGroup;
- UInt32 transmitBuffersSize;
- UInt32 emptyPacketNumerator;
- float A, B, C, d, n;
- OSStatus status = noErr;
-
- // Process the buffer.
- pBuffer = (UInt32 *) pAVTPlaySnapShotParams->snapShotBuffer;
- snapShotBufferSize = pAVTPlaySnapShotParams->snapShotBufferSize;
- matchIndex = 0;
- for (i = 0; i < snapShotBufferSize; i++)
- {
- // Read next buffer value.
- bufferValue = *pBuffer++;
-
- // Check for match.
- if ((bufferValue & matchMask[matchIndex]) == matchValue[matchIndex])
- matchIndex++;
- else
- matchIndex = 0;
-
- // Check for start of frame if we've matched enough.
- if (matchIndex == 2)
- {
- if (((bufferValue & 0x00000C00) != 0x00000C00) &&
- (!((pBuffer[0] & matchMask[0]) == matchValue[0])))
- break;
- else
- matchIndex = 0;
- }
- }
- pBuffer -= 2;
-
- // Check if we have enough data left.
- goodSnapShotBufferSize =
- snapShotBufferSize -
- (((UInt32) pBuffer) -
- ((UInt32) pAVTPlaySnapShotParams->snapShotBuffer));
- if (goodSnapShotBufferSize < kMinDVFrameSize)
- status = -1;
-
- // Compact data.
- if (status == noErr)
- {
- pCompactBuffer = (UInt32 *) pAVTPlaySnapShotParams->snapShotBuffer;
- for (dataPacketNum = 0; dataPacketNum < kNumDVPacketsPerFrame; dataPacketNum++)
- {
- if ((pBuffer[2] & matchMask[0]) != matchValue[0])
- {
- BlockCopy (pBuffer + 2, pCompactBuffer, 480);
- pBuffer += 122;
- pCompactBuffer += 120;
- }
-
- while ((pBuffer[2] & matchMask[0]) == matchValue[0])
- pBuffer += 2;
- }
-
- gpFWAVCDriverData->imageBuffer = pAVTPlaySnapShotParams->snapShotBuffer;
- }
-
- // Compute nominal frame period cycle time.
- if (status == noErr)
- {
- gpFWAVCDriverData->nominalFrameCycleTime =
- FWAVCConvertFractionalSecondsToCycleTime
- (kPlayFramePeriodNumerator, kPlayFramePeriodDenominator);
- }
-
- // Compute the number of data packets per empty packet.
- // If the frame rate is expressed as n/d, the number of data packets per buffer group
- // expressed as A, and the number of data packets per frame as C, then the number of
- // empty packets per buffer group B should be
- //
- // B = int (8000*d/n*A/C - A + 1)
- //
- // in order to ensure that the frame rate may be maintained by periodically reducing
- // the number of empty packets in a buffer group by 1.
- //
- if (status == noErr)
- {
- A = (float) kNumDataPacketsPerPlayBufferGroup;
- C = (float) kNumDataPacketsPerDVFrame;
- n = (float) kPlayFrameRateNumerator;
- d = (float) kPlayFrameRateDenominator;
- B = 8000.0*d/n*A/C - A + 1;
- numEmptyPacketsPerPlayBufferGroup = (UInt32) B;
- }
-
- // Allocate transmit buffers.
- if (status == noErr)
- {
- if (gpFWAVCDriverData->transmitBuffers == nil)
- {
- // Compute size.
- transmitBuffersSize =
- kNumDataPacketsPerPlayBufferGroup * (kDVPacketCIPSize + kDVPacketDataSize);
- transmitBuffersSize +=
- numEmptyPacketsPerPlayBufferGroup * kDVPacketCIPSize;
- transmitBuffersSize *= kNumPlayBufferGroups;
-
- // Allocate.
- gpFWAVCDriverData->transmitBuffers =
- PoolAllocateResident (transmitBuffersSize, false);
- if (gpFWAVCDriverData->transmitBuffers == nil)
- status = memFullErr;
- }
- pTransmitBuffer = (UInt32 *) gpFWAVCDriverData->transmitBuffers;
- }
-
- // Allocate DCL command pool.
- if (status == noErr)
- {
- pDCLCommandPool = FWAVCAllocateDCLCommandPool ();
- if (pDCLCommandPool != nil)
- gpFWAVCDriverData->pPlayDCLCommandPool = pDCLCommandPool;
- else
- status = memFullErr;
- }
-
- // Fill in buffers.
- if (status == noErr)
- {
- // Initialize total packet count.
- gpFWAVCDriverData->totalPlayPackets = 0;
-
- // Create label for start of loop.
- pLoopDCLLabel = (DCLLabelPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLLabel));
- pDCLCommand = (DCLCommandPtr) pLoopDCLLabel;
- gpFWAVCDriverData->playDCLList = pDCLCommand;
- pLoopDCLLabel->opcode = kDCLLabelOp;
-
- // Set isoch packet tag bits.
- pDCLSetTagSyncBits = (DCLSetTagSyncBitsPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLSetTagSyncBits));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLSetTagSyncBits;
- pDCLCommand = (DCLCommandPtr) pDCLSetTagSyncBits;
- pDCLSetTagSyncBits->opcode = kDCLSetTagSyncBitsOp;
- pDCLSetTagSyncBits->tagBits = 1;
- pDCLSetTagSyncBits->syncBits = 0;
-
- for (bufferGroupNum = 0; bufferGroupNum < kNumPlayBufferGroups; bufferGroupNum++)
- {
- // Allocate a buffer group data record.
- pFWAVCPlayBufferGroupData = FWAVCAllocatePlayBufferGroup (gpFWAVCDriverData);
-
- // Initialize for loop.
- dataPacketNum = 0;
- numPackets = 0;
- emptyPacketNumerator = 0;
- pFirstBufferGroupDCLCommand = nil;
- pBufferGroupSkipEmptyPacketDCLLabel = nil;
-
- while (dataPacketNum < kNumDataPacketsPerPlayBufferGroup)
- {
- // Send a packet.
- // CIP header.
- pDCLTransferPacket = (DCLTransferPacketPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLTransferPacket));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
- pDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
- pDCLTransferPacket->opcode = kDCLSendPacketStartOp;
- pDCLTransferPacket->buffer = (Ptr) pTransmitBuffer;
- pDCLTransferPacket->size = 8;
-
- pTransmitBuffer += 2;
-
- // Save first data packet DCL command.
- if (pFirstBufferGroupDCLCommand == nil)
- pFirstBufferGroupDCLCommand = (DCLCommandPtr) pDCLCommand;
-
- // Payload.
- pDCLTransferPacket = (DCLTransferPacketPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLTransferPacket));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
- pDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
- pDCLTransferPacket->opcode = kDCLSendPacketOp;
- pDCLTransferPacket->buffer = (Ptr) pTransmitBuffer;
- pDCLTransferPacket->size = 480;
-
- pTransmitBuffer += 120;
- dataPacketNum++;
- numPackets++;
- emptyPacketNumerator += numEmptyPacketsPerPlayBufferGroup;
-
- if (emptyPacketNumerator >= kNumDataPacketsPerPlayBufferGroup)
- {
- // Add skip jump if this is the first empty packet in the buffer group.
- if (pBufferGroupSkipEmptyPacketDCLLabel == nil)
- {
- pDCLJump = (DCLJumpPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLJump));
- pFWAVCPlayBufferGroupData->pBufferGroupSkipEmptyPacketDCLJump =
- pDCLJump;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLJump;
- pDCLCommand = (DCLCommandPtr) pDCLJump;
- pDCLJump->opcode = kDCLJumpOp | kFWDCLOpDynamicFlag;
-
- pDCLLabel = (DCLLabelPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLLabel));
- pFWAVCPlayBufferGroupData->pBufferGroupDontSkipEmptyPacketDCLLabel =
- pDCLLabel;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLLabel;
- pDCLCommand = (DCLCommandPtr) pDCLLabel;
- pDCLLabel->opcode = kDCLLabelOp;
-
- pDCLJump->pJumpDCLLabel = pDCLLabel;
- }
-
- // Send a packet.
- // Just CIP header.
- pDCLTransferPacket = (DCLTransferPacketPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool,
- sizeof (DCLTransferPacket));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
- pDCLCommand = (DCLCommandPtr) pDCLTransferPacket;
- pDCLTransferPacket->opcode = kDCLSendPacketStartOp;
- pDCLTransferPacket->buffer = (Ptr) pTransmitBuffer;
- pDCLTransferPacket->size = 8;
-
- pTransmitBuffer += 2;
- numPackets++;
- emptyPacketNumerator -= kNumDataPacketsPerPlayBufferGroup;
-
- // Add skip jump label if this is the first empty packet in the
- // buffer group.
- if (pBufferGroupSkipEmptyPacketDCLLabel == nil)
- {
- // Add skip label.
- pDCLLabel = (DCLLabelPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLLabel));
- pBufferGroupSkipEmptyPacketDCLLabel = pDCLLabel;
- pFWAVCPlayBufferGroupData->pBufferGroupSkipEmptyPacketDCLLabel =
- pBufferGroupSkipEmptyPacketDCLLabel;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLLabel;
- pDCLCommand = (DCLCommandPtr) pDCLLabel;
- pDCLLabel->opcode = kDCLLabelOp;
- }
- }
- }
-
- // Save number of packets in this buffer group, DCL update list size, and last
- // DCL command.
- pFWAVCPlayBufferGroupData->numPackets = numPackets;
- pFWAVCPlayBufferGroupData->pFirstBufferGroupDCLCommand =
- pFirstBufferGroupDCLCommand;
- pFWAVCPlayBufferGroupData->pLastBufferGroupDCLCommand =
- (DCLCommandPtr) pDCLCommand;
-
- // Create buffer group update list.
- FWAVCCreatePlayBufferGroupUpdateList (pFWAVCPlayBufferGroupData);
-
- // Update total packet count.
- gpFWAVCDriverData->totalPlayPackets += numPackets;
-
- // Create end of buffer group jump.
- pBufferGroupDCLJump = (DCLJumpPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLJump));
- pFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLJump = pBufferGroupDCLJump;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pBufferGroupDCLJump;
- pDCLCommand = (DCLCommandPtr) pBufferGroupDCLJump;
- pBufferGroupDCLJump->opcode = kDCLJumpOp | kFWDCLOpDynamicFlag;
-
- // Create label for end of buffer group.
- pBufferGroupDCLLabel = (DCLLabelPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLLabel));
- pFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLLabel = pBufferGroupDCLLabel;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pBufferGroupDCLLabel;
- pDCLCommand = (DCLCommandPtr) pBufferGroupDCLLabel;
- pBufferGroupDCLLabel->opcode = kDCLLabelOp;
-
- // Set end of buffer group jump to jump to end of buffer group.
- pBufferGroupDCLJump->pJumpDCLLabel = pBufferGroupDCLLabel;
-
- // Get time stamp at end of buffer group.
- pDCLTimeStamp = (DCLTimeStampPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLTimeStamp));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLTimeStamp;
- pDCLCommand = (DCLCommandPtr) pDCLTimeStamp;
- pDCLTimeStamp->opcode = kDCLTimeStampOp;
- pFWAVCPlayBufferGroupData->pBufferGroupDCLTimeStamp = pDCLTimeStamp;
- pFWAVCPlayBufferGroupData->timeStampUpdateDCLList =
- (DCLCommandPtr) pDCLTimeStamp;
-
- // Create update DCL list to update time stamp.
- pDCLUpdateDCLList = (DCLUpdateDCLListPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLUpdateDCLList));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLUpdateDCLList;
- pDCLCommand = (DCLCommandPtr) pDCLUpdateDCLList;
- pDCLUpdateDCLList->opcode = kDCLUpdateDCLListOp;
- pDCLUpdateDCLList->dclCommandList =
- &(pFWAVCPlayBufferGroupData->timeStampUpdateDCLList);
- pDCLUpdateDCLList->numDCLCommands = 1;
-
- // Call a proc at end of buffer group.
- pDCLCallProc = (DCLCallProcPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLCallProc));
- pFWAVCPlayBufferGroupData->pBufferGroupDCLCallProc = pDCLCallProc;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLCallProc;
- pDCLCommand = (DCLCommandPtr) pDCLCallProc;
- pDCLCallProc->opcode = kDCLCallProcOp;
- pDCLCallProc->proc = FWAVCHandleDVSend;
- pDCLCallProc->procData = (UInt32) pFWAVCPlayBufferGroupData;
-
- // Create update DCL list to update buffers.
- pDCLUpdateDCLList = (DCLUpdateDCLListPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLUpdateDCLList));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLUpdateDCLList;
- pDCLCommand = (DCLCommandPtr) pDCLUpdateDCLList;
- pDCLUpdateDCLList->opcode = kDCLUpdateDCLListOp;
- pDCLUpdateDCLList->dclCommandList =
- pFWAVCPlayBufferGroupData->bufferGroupUpdateDCLList;
- pDCLUpdateDCLList->numDCLCommands = pFWAVCPlayBufferGroupData->updateListSize;
- }
-
- // Loop to first buffer group.
- pDCLJump = (DCLJumpPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLJump));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLJump;
- pDCLCommand = (DCLCommandPtr) pDCLJump;
- pDCLJump->opcode = kDCLJumpOp | kFWDCLOpDynamicFlag;
- pDCLJump->pJumpDCLLabel = pLoopDCLLabel;
-
- // Create label for underrun.
- pUnderrunDCLLabel = (DCLLabelPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLLabel));
- gpFWAVCDriverData->pUnderrunDCLLabel = pUnderrunDCLLabel;
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pUnderrunDCLLabel;
- pDCLCommand = (DCLCommandPtr) pUnderrunDCLLabel;
- pUnderrunDCLLabel->opcode = kDCLLabelOp;
-
- // Set last buffer group's jump DCL to jump to underrun.
- pBufferGroupDCLJump->pJumpDCLLabel = pUnderrunDCLLabel;
-
- // Call underrun proc.
- // This is the last command.
- pDCLCallProc = (DCLCallProcPtr)
- FWAVCAllocateDCLCommand (pDCLCommandPool, sizeof (DCLCallProc));
- pDCLCommand->pNextDCLCommand = (DCLCommandPtr) pDCLCallProc;
- pDCLCallProc->pNextDCLCommand = nil;
- pDCLCallProc->opcode = kDCLCallProcOp;
- pDCLCallProc->proc = FWAVCHandleDVSendUnderrun;
- pDCLCallProc->procData = (UInt32) gpFWAVCDriverData;
-
- // Initialize number of active play packets.
- gpFWAVCDriverData->activePlayPackets = gpFWAVCDriverData->totalPlayPackets;
- }
-
- // Set up all of the buffer groups.
- if (status == noErr)
- {
- gpFWAVCDriverData->nextSYT = kPlaySYTDelay;
- pFWAVCPlayBufferGroupData = gpFWAVCDriverData->pFWAVCPlayBufferGroupDataList;
- for (bufferGroupNum = 0; bufferGroupNum < kNumPlayBufferGroups; bufferGroupNum++)
- {
- FWAVCUpdateDVSendBuffers
- ((DCLCommandPtr) pFWAVCPlayBufferGroupData->pBufferGroupDCLCallProc);
- pFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData->pNextFWAVCPlayBufferGroupData;
- }
- }
-
- // Set start of DCL program.
- if (status == noErr)
- {
- status = FWSetDCLProgramStart (gpFWAVCDriverData->playDCLProgramID,
- gpFWAVCDriverData->playDCLList);
- }
-
- // Set start event for DCL program
- if (status == noErr)
- {
- status = FWSetDCLProgramStartEvent (gpFWAVCDriverData->playDCLProgramID,
- kFWDCLCycleEvent,
- 0,
- BitRange (12, 15));
- }
-
- // Initialize the isochrounous channel.
- if (status == noErr)
- {
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->playIsochChannelID);
-
- status = FWInitializeIsochronousChannel (isochChannelCommandObjectID);
- if (status == noErr)
- gpFWAVCDriverData->playSnapShotChannelInitialized = true;
- }
-
- // Start the isochronous channel for playing.
- if (status == noErr)
- {
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->playIsochChannelID);
-
- status = FWStartIsochronousChannel (isochChannelCommandObjectID);
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCStopSnapShot
- //
- // This routine stops a snapshot video stream.
- //
-
- static OSStatus FWAVCStopSnapShot(
- AVTInterfaceParamsPtr pAVTInterfaceParams)
- {
- FWCommandObjectID isochChannelCommandObjectID;
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData,
- pNextFWAVCPlayBufferGroupData;
- UInt32 bufferGroupNum;
- OSStatus status = noErr;
-
- // Stop the snap shot.
- if (gpFWAVCDriverData->playSnapShotChannelInitialized)
- {
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->playIsochChannelID);
-
- FWStopIsochronousChannel (isochChannelCommandObjectID);
-
- isochChannelCommandObjectID = gpFWAVCDriverData->isochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- kFWCommandSyncFlag,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- gpFWAVCDriverData->playIsochChannelID);
-
- FWReleaseIsochronousChannel (isochChannelCommandObjectID);
-
- // Deallocate play buffer group data records.
- pFWAVCPlayBufferGroupData = gpFWAVCDriverData->pFWAVCPlayBufferGroupDataList;
- if (pFWAVCPlayBufferGroupData != nil)
- {
- for (bufferGroupNum = 0;
- bufferGroupNum < kNumPlayBufferGroups;
- bufferGroupNum++)
- {
- pNextFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData->pNextFWAVCPlayBufferGroupData;
- FWAVCDeallocatePlayBufferGroup (pFWAVCPlayBufferGroupData);
- pFWAVCPlayBufferGroupData = pNextFWAVCPlayBufferGroupData;
- }
- }
- gpFWAVCDriverData->pFWAVCPlayBufferGroupDataList = nil;
-
- FWAVCDeallocateDCLCommandPool (gpFWAVCDriverData->pPlayDCLCommandPool);
- gpFWAVCDriverData->pPlayDCLCommandPool = nil;
-
- PoolDeallocate (gpFWAVCDriverData->transmitBuffers);
- gpFWAVCDriverData->transmitBuffers = nil;
-
- gpFWAVCDriverData->playSnapShotChannelInitialized = false;
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCDVPingPong
- //
- // This routine handles ping pong DV dumping.
- //
-
- static void FWAVCDVPingPong(
- DCLCommandPtr pDCLCommandPtr)
- {
- FWAVCDVPingPongDataPtr pFWAVCDVPingPongData;
- FWAVCDriverDataPtr pFWAVCDriverData;
- AVTDumpParamsPtr pAVTDumpParams;
- DCLCallProcPtr pDCLCallProc;
- DCLCommandPtr pCurrentDCLCommand;
- DCLTransferPacketPtr pDCLTransferPacket;
- UInt32 transferSize;
- Ptr packetBuffer;
- UInt32 packetHeader;
- UInt32 packetSize;
- Ptr dumpBuffer;
- UInt32 dumpBufferLeft;
- UInt32 dumpBufferOffset;
- UInt32 packetNum;
-
- // Recast DCL command.
- pDCLCallProc = (DCLCallProcPtr) pDCLCommandPtr;
-
- // Get ping pong data.
- pFWAVCDVPingPongData = (FWAVCDVPingPongDataPtr) pDCLCallProc->procData;
-
- // Get info from ping pong data.
- pFWAVCDriverData = pFWAVCDVPingPongData->pFWAVCDriverData;
- pCurrentDCLCommand = pFWAVCDVPingPongData->pFirstDCLCommand;
- pAVTDumpParams = pFWAVCDriverData->pAVTDumpParams;
- dumpBufferOffset = pAVTDumpParams->dumpBufferOffset;
- dumpBuffer = pAVTDumpParams->dumpBuffer;
- dumpBufferLeft = pAVTDumpParams->dumpBufferSize - dumpBufferOffset;
-
- // Copy data from packets.
- for (packetNum = 0;
- ((packetNum < kNumPacketsPerPingPong) && (dumpBufferLeft > 0));
- packetNum++)
- {
- // Compute size of transfer.
- pDCLTransferPacket = (DCLTransferPacketPtr) pCurrentDCLCommand;
- packetBuffer = pDCLTransferPacket->buffer;
- packetHeader = *((UInt32 *) packetBuffer);
- packetBuffer += 4;
- packetSize = (packetHeader & kFWIsochDataLength) >> kFWIsochDataLengthPhase;
- if (packetSize < dumpBufferLeft)
- transferSize = packetSize;
- else
- transferSize = dumpBufferLeft;
-
- // Do transfer.
- BlockCopy (packetBuffer, dumpBuffer + dumpBufferOffset, transferSize);
-
- // Update for next packet.
- pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
- dumpBufferLeft -= transferSize;
- dumpBufferOffset += transferSize;
- }
-
- // Update dump buffer params.
- pAVTDumpParams->dumpBufferOffset = dumpBufferOffset;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCHandleDVSend
- //
- // This routine handles isochronous sending of DV data.
- //
-
- static void FWAVCHandleDVSend(
- DCLCommandPtr pDCLCommandPtr)
- {
- DCLCallProcPtr pDCLCallProc;
- DCLTimeStampPtr pDCLTimeStamp;
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData,
- pPrevFWAVCPlayBufferGroupData;
- FWAVCDriverDataPtr pFWAVCDriverData;
- UInt32 nominalFrameCycleTime;
- UInt32 fractionalFrameCycleCount,
- fractionalFrameCycleOffset;
- SInt32 timeDrift;
- UInt32 projectedTimeStamp,
- projectedSYT;
-
- // Recast pDCLCommandPtr.
- pDCLCallProc = (DCLCallProcPtr) pDCLCommandPtr;
-
- // Get data for buffer group and driver data.
- pFWAVCPlayBufferGroupData = (FWAVCPlayBufferGroupDataPtr) pDCLCallProc->procData;
- pFWAVCDriverData = pFWAVCPlayBufferGroupData->pFWAVCDriverData;
- nominalFrameCycleTime = pFWAVCDriverData->nominalFrameCycleTime;
-
- // Undo skipping empty packet if we're currently skipping a packet.
- if (pFWAVCPlayBufferGroupData->skippingEmptyPacket)
- {
- FWModifyDCLJump
- (pFWAVCDriverData->playDCLProgramID,
- pFWAVCPlayBufferGroupData->pBufferGroupSkipEmptyPacketDCLJump,
- pFWAVCPlayBufferGroupData->pBufferGroupDontSkipEmptyPacketDCLLabel);
- pFWAVCDriverData->activePlayPackets++;
- pFWAVCPlayBufferGroupData->skippingEmptyPacket = false;
- }
-
- // Get data for previous buffer group.
- pPrevFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData->pPrevFWAVCPlayBufferGroupData;
-
- // Compute time drift.
-
- // Compute the projected time stamp value for the first packet of the current
- // buffer group the next time this proc is called for the current buffer group.
-
- // Start at time stamp of first packet in next buffer group to be sent.
- pDCLTimeStamp = pFWAVCPlayBufferGroupData->pBufferGroupDCLTimeStamp;
- projectedTimeStamp = pDCLTimeStamp->timeStamp + 1;
-
- // Add the total number of cycles for all active buffer group packets.
- projectedTimeStamp += pFWAVCDriverData->activePlayPackets << 12;
-
- // Subtract the number of cycles for all packets in the current buffer group.
- projectedTimeStamp -= pFWAVCPlayBufferGroupData->numPackets << 12;
-
- // Compute the projected SYT value for the first packet of the current buffer group
- // the next time this proc is called for the current buffer group.
-
- // Start with the SYT value to use for the first packet of the next frame.
- projectedSYT = pFWAVCDriverData->nextSYT;
-
- // Subtract the SYT offset between frames.
- projectedSYT =
- FWAVCSubtractCycleTimeFromCycleTime (projectedSYT, nominalFrameCycleTime);
-
- // Add the fraction of the SYT offset between the start of the frame and the
- // first data packet for the current buffer group.
- fractionalFrameCycleOffset =
- ((nominalFrameCycleTime & 0x0FFF) * pFWAVCDriverData->nextDataPacketNum) /
- kNumDataPacketsPerDVFrame;
-
- fractionalFrameCycleCount =
- ((nominalFrameCycleTime & 0x01FFF000) * pFWAVCDriverData->nextDataPacketNum) /
- kNumDataPacketsPerDVFrame;
- fractionalFrameCycleCount =
- (fractionalFrameCycleCount & 0x01FFF000) +
- (((fractionalFrameCycleCount & 0x0FFF) * 3072) / 4096);
-
- projectedSYT = FWAVCAddCycleTimeToCycleTime (projectedSYT, fractionalFrameCycleOffset);
- projectedSYT = FWAVCAddCycleTimeToCycleTime (projectedSYT, fractionalFrameCycleCount);
-
- // The time drift is the difference between the projected time stamp and SYT.
- // We must convert the time drift to cycles.
- timeDrift = (projectedTimeStamp >> 12) + kPlaySYTDelay - (projectedSYT >> 12);
- timeDrift &= 0x0F;
-
- // Skip an empty packet if we're drifting.
- // Only consider positive drifting.
- if ((timeDrift > 0) && (timeDrift < 8))
- {
- FWModifyDCLJump (pFWAVCDriverData->playDCLProgramID,
- pFWAVCPlayBufferGroupData->pBufferGroupSkipEmptyPacketDCLJump,
- pFWAVCPlayBufferGroupData->pBufferGroupSkipEmptyPacketDCLLabel);
- pFWAVCDriverData->activePlayPackets--;
- pFWAVCPlayBufferGroupData->skippingEmptyPacket = true;
- }
-
- FWAVCUpdateDVSendBuffers (pDCLCommandPtr);
-
- // Update DCL jumps to call underrun proc after this buffer group.
- //zzz check errors.
- FWModifyDCLJump (pFWAVCDriverData->playDCLProgramID,
- pFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLJump,
- pFWAVCDriverData->pUnderrunDCLLabel);
- FWModifyDCLJump (pFWAVCDriverData->playDCLProgramID,
- pPrevFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLJump,
- pPrevFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLLabel);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCUpdateDVSendBuffers
- //
- // This routine updates the buffers for sending DV data.
- //
-
- static void FWAVCUpdateDVSendBuffers(
- DCLCommandPtr pDCLCommandPtr)
- {
- DCLCommandPtr pCurrentDCLCommand;
- DCLCallProcPtr pDCLCallProc;
- DCLTransferPacketPtr pDCLTransferPacket;
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData,
- pPrevFWAVCPlayBufferGroupData;
- FWAVCDriverDataPtr pFWAVCDriverData;
- UInt32 localNodeID;
- UInt32 generation;
- UInt32 nominalFrameCycleTime;
- UInt32 syt;
- UInt32 *pBuffer,
- *pImageBuffer;
- UInt32 packetNum,
- dataPacketNum,
- numPackets;
- UInt32 dbc;
-
- // Recast pDCLCommandPtr.
- pDCLCallProc = (DCLCallProcPtr) pDCLCommandPtr;
-
- // Get data for buffer group.
- pFWAVCPlayBufferGroupData = (FWAVCPlayBufferGroupDataPtr) pDCLCallProc->procData;
-
- // Get driver data and first DCL command.
- pFWAVCDriverData = pFWAVCPlayBufferGroupData->pFWAVCDriverData;
- pCurrentDCLCommand = pFWAVCPlayBufferGroupData->pFirstBufferGroupDCLCommand;
- nominalFrameCycleTime = pFWAVCDriverData->nominalFrameCycleTime;
-
- // Get data for previous buffer group.
- pPrevFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData->pPrevFWAVCPlayBufferGroupData;
- syt = pFWAVCDriverData->nextSYT;
- dbc = pFWAVCDriverData->nextDBC;
- dataPacketNum = pFWAVCDriverData->nextDataPacketNum;
-
- // Get local node ID.
- FWGetNodeID (pFWAVCDriverData->localFWReferenceID, &localNodeID, &generation);
-
- // Get first send packet command for this buffer group.
- while (pCurrentDCLCommand->opcode != kDCLSendPacketStartOp)
- pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
- pDCLTransferPacket = (DCLTransferPacketPtr) pCurrentDCLCommand;
-
- // Update the packet buffers.
- numPackets = pFWAVCPlayBufferGroupData->numPackets;
- pImageBuffer = (UInt32 *) (pFWAVCDriverData->imageBuffer + 480*dataPacketNum);
- for (packetNum = 0; packetNum < numPackets; packetNum++)
- {
- // Set up packet header.
- pBuffer = (UInt32 *) pDCLTransferPacket->buffer;
- pBuffer[0] = 0x00780000 | (localNodeID << 24) | (dbc & 0xFF);
- pBuffer[1] = 0x8000FFFF;
-
- // See if this is a data packet.
- pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
- if (pCurrentDCLCommand != nil)
- {
- if (pCurrentDCLCommand->opcode == kDCLSendPacketOp)
- {
- // Set SYT field if this is the first data packet in the frame.
- if (dataPacketNum == 0)
- {
- pBuffer[1] = 0x80000000 | (syt & 0xFFFF);
-
- // Increment next syt by one frame period.
- pFWAVCDriverData->sytNumerator += kPlayFramePeriodNumerator;
- if (pFWAVCDriverData->sytNumerator > kPlayFramePeriodDenominator)
- pFWAVCDriverData->sytNumerator -= kPlayFramePeriodDenominator;
- syt = FWAVCConvertFractionalSecondsToCycleTime
- (pFWAVCDriverData->sytNumerator, kPlayFramePeriodDenominator);
- }
-
- // Copy data into packet.
- pDCLTransferPacket = (DCLTransferPacketPtr) pCurrentDCLCommand;
- BlockCopy (pImageBuffer, pDCLTransferPacket->buffer, 480);
- pImageBuffer += 120;
- dbc++;
- dataPacketNum++;
- if (dataPacketNum == kNumDataPacketsPerDVFrame)
- {
- pImageBuffer = (UInt32 *) pFWAVCDriverData->imageBuffer;
- dataPacketNum = 0;
- }
- }
- }
-
- // Find next send packet start command.
- while (pCurrentDCLCommand != nil)
- {
- if (pCurrentDCLCommand->opcode != kDCLSendPacketStartOp)
- pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand;
- else
- break;
- }
- pDCLTransferPacket = (DCLTransferPacketPtr) pCurrentDCLCommand;
- }
- pFWAVCDriverData->nextSYT = syt;
- pFWAVCDriverData->nextDBC = dbc;
- pFWAVCDriverData->nextDataPacketNum = dataPacketNum;
-
- // Call to update DCL's if we need to. We have to do this on underrun because the update
- // DCL command won't be run to reflect the changes we've made here.
- if (pFWAVCPlayBufferGroupData->needsUpdate)
- {
- FWUpdateDCLList (pFWAVCDriverData->playDCLProgramID,
- pFWAVCPlayBufferGroupData->bufferGroupUpdateDCLList,
- pFWAVCPlayBufferGroupData->updateListSize);
- pFWAVCPlayBufferGroupData->needsUpdate = false;
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCHandleDVSendUnderrun
- //
- // This routine handles underruns for sending DV data.
- //
-
- static void FWAVCHandleDVSendUnderrun(
- DCLCommandPtr pDCLCommandPtr)
- {
- DCLCallProcPtr pDCLCallProc;
- FWAVCDriverDataPtr pFWAVCDriverData;
- FWCommandObjectID isochChannelCommandObjectID;
-
- // Recast pDCLCommandPtr.
- pDCLCallProc = (DCLCallProcPtr) pDCLCommandPtr;
-
- // Get driver data.
- pFWAVCDriverData = (FWAVCDriverDataPtr) pDCLCallProc->procData;
-
- // Set up params for stopping isochronous channel.
- isochChannelCommandObjectID = pFWAVCDriverData->stopIsochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- 0,
- FWAVCHandleDVSendUnderrunStopIsochronousChannelCompletionProc,
- (UInt32) pDCLCallProc);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- pFWAVCDriverData->playIsochChannelID);
-
- // Stop the isochronous channel.
- FWStopIsochronousChannel (isochChannelCommandObjectID);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCHandleDVSendUnderrunStopIsochronousChannelCompletionProc
- //
- // This routine handles underruns for sending DV data.
- //
-
- static void FWAVCHandleDVSendUnderrunStopIsochronousChannelCompletionProc(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData)
- {
- DCLCallProcPtr pDCLCallProc;
- FWAVCDriverDataPtr pFWAVCDriverData;
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData;
- FWCommandObjectID isochChannelCommandObjectID;
- UInt32 bufferGroupNum;
-
- // Get DCL call proc data.
- pDCLCallProc = (DCLCallProcPtr) completionProcData;
-
- // Get driver data.
- pFWAVCDriverData = (FWAVCDriverDataPtr) pDCLCallProc->procData;
-
- // Reset next SYT, dbc, and data packet num.
- pFWAVCDriverData->nextSYT = kPlaySYTDelay;
- pFWAVCDriverData->nextDBC = 0;
- pFWAVCDriverData->nextDataPacketNum = 0;
-
- // Reset up all of the buffer groups.
- pFWAVCPlayBufferGroupData = pFWAVCDriverData->pFWAVCPlayBufferGroupDataList;
- for (bufferGroupNum = 0; bufferGroupNum < kNumPlayBufferGroups; bufferGroupNum++)
- {
- // Update buffer group buffers.
- pFWAVCPlayBufferGroupData->needsUpdate = true;
- FWAVCUpdateDVSendBuffers
- ((DCLCommandPtr) pFWAVCPlayBufferGroupData->pBufferGroupDCLCallProc);
-
- // Update buffer group jump DCL.
- if (bufferGroupNum < (kNumPlayBufferGroups - 1))
- {
- FWModifyDCLJump (pFWAVCDriverData->playDCLProgramID,
- pFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLJump,
- pFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLLabel);
- }
- else
- {
- FWModifyDCLJump (pFWAVCDriverData->playDCLProgramID,
- pFWAVCPlayBufferGroupData->pEndOfBufferGroupDCLJump,
- pFWAVCDriverData->pUnderrunDCLLabel);
- }
-
- pFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData->pNextFWAVCPlayBufferGroupData;
- }
-
- // Set up params for starting isochronous channel.
- isochChannelCommandObjectID = pFWAVCDriverData->startIsochChannelCommandObjectID;
- FWSetFWCommandParams (isochChannelCommandObjectID,
- kInvalidFWReferenceID,
- 0,
- nil,
- 0);
- FWSetIsochChannelCommandIsochChannelID (isochChannelCommandObjectID,
- pFWAVCDriverData->playIsochChannelID);
-
- // Restart the isochronous channel.
- FWStartIsochronousChannel (isochChannelCommandObjectID);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCClientCommandCompletionProc
- //
- // This routine does generic completion of FireWire client commands that
- // make asynchronous FireWire service calls.
- //
-
- static void FWAVCClientCommandCompletionProc(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData)
- {
- FWClientCommandIsComplete ((FWClientCommandID) completionProcData, commandStatus);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCAllocatePlayBufferGroup
- //
- // This routine allocates a buffer group for playing.
- //
-
- static FWAVCPlayBufferGroupDataPtr FWAVCAllocatePlayBufferGroup(
- FWAVCDriverDataPtr pFWAVCDriverData)
- {
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData = nil,
- pPrevFWAVCPlayBufferGroupData,
- pNextFWAVCPlayBufferGroupData;
- OSStatus status = noErr;
-
- // Allocate buffer group data record.
- pFWAVCPlayBufferGroupData = (FWAVCPlayBufferGroupDataPtr)
- PoolAllocateResident (sizeof (FWAVCPlayBufferGroupData), true);
- if (pFWAVCPlayBufferGroupData != nil)
- pFWAVCPlayBufferGroupData->pFWAVCDriverData = pFWAVCDriverData;
- else
- status = memFullErr;
-
- // Insert buffer group data record into list.
- if (status == noErr)
- {
- pNextFWAVCPlayBufferGroupData = pFWAVCDriverData->pFWAVCPlayBufferGroupDataList;
- if (pNextFWAVCPlayBufferGroupData != nil)
- {
- pPrevFWAVCPlayBufferGroupData =
- pNextFWAVCPlayBufferGroupData->pPrevFWAVCPlayBufferGroupData;
-
- pNextFWAVCPlayBufferGroupData->pPrevFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData;
- pFWAVCPlayBufferGroupData->pNextFWAVCPlayBufferGroupData =
- pNextFWAVCPlayBufferGroupData;
- }
- else
- {
- pPrevFWAVCPlayBufferGroupData = pFWAVCPlayBufferGroupData;
-
- pFWAVCDriverData->pFWAVCPlayBufferGroupDataList = pFWAVCPlayBufferGroupData;
- }
-
- pPrevFWAVCPlayBufferGroupData->pNextFWAVCPlayBufferGroupData =
- pFWAVCPlayBufferGroupData;
- pFWAVCPlayBufferGroupData->pPrevFWAVCPlayBufferGroupData =
- pPrevFWAVCPlayBufferGroupData;
- }
-
- return (pFWAVCPlayBufferGroupData);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCDeallocatePlayBufferGroup
- //
- // This routine deallocates a buffer group for playing.
- //
-
- static void FWAVCDeallocatePlayBufferGroup(
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData)
- {
- if (pFWAVCPlayBufferGroupData != nil)
- {
- if (pFWAVCPlayBufferGroupData->bufferGroupUpdateDCLList != nil)
- PoolDeallocate ((Ptr) pFWAVCPlayBufferGroupData->bufferGroupUpdateDCLList);
-
- PoolDeallocate (pFWAVCPlayBufferGroupData);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCCreatePlayBufferGroupUpdateList
- //
- // This routine creates the update list for a play buffer group.
- //
-
- static OSStatus FWAVCCreatePlayBufferGroupUpdateList(
- FWAVCPlayBufferGroupDataPtr pFWAVCPlayBufferGroupData)
- {
- DCLCommandPtr pDCLCommand,
- pLastDCLCommand;
- DCLCommandPtr *updateDCLList,
- *pUpdateDCLListEntry;
- UInt32 opcode;
- UInt32 updateListSize;
- OSStatus status = noErr;
-
- // Loop through all DCL commands in buffer group and count all send packet DCL
- // commands.
- pDCLCommand = pFWAVCPlayBufferGroupData->pFirstBufferGroupDCLCommand;
- pLastDCLCommand = pFWAVCPlayBufferGroupData->pLastBufferGroupDCLCommand;
- updateListSize = 0;
- while (pDCLCommand != pLastDCLCommand)
- {
- opcode = pDCLCommand->opcode & ~kFWDCLOpFlagMask;
- if ((opcode == kDCLSendPacketStartOp) || (opcode == kDCLSendPacketOp))
- updateListSize++;
-
- pDCLCommand = pDCLCommand->pNextDCLCommand;
- }
- opcode = pDCLCommand->opcode & ~kFWDCLOpFlagMask;
- if ((opcode == kDCLSendPacketStartOp) || (opcode == kDCLSendPacketOp))
- updateListSize++;
-
- // Allocate update list.
- updateDCLList = (DCLCommandPtr *)
- PoolAllocateResident (updateListSize * sizeof (DCLCommandPtr), false);
- if (updateDCLList == nil)
- status = memFullErr;
-
- // Loop through all DCL commands in buffer group and add all send packet DCL
- // commands to update list.
- if (status == noErr)
- {
- pDCLCommand = pFWAVCPlayBufferGroupData->pFirstBufferGroupDCLCommand;
- pLastDCLCommand = pFWAVCPlayBufferGroupData->pLastBufferGroupDCLCommand;
- pUpdateDCLListEntry = updateDCLList;
-
- while (pDCLCommand != pLastDCLCommand)
- {
- opcode = pDCLCommand->opcode & ~kFWDCLOpFlagMask;
- if ((opcode == kDCLSendPacketStartOp) || (opcode == kDCLSendPacketOp))
- *pUpdateDCLListEntry++ = pDCLCommand;
-
- pDCLCommand = pDCLCommand->pNextDCLCommand;
- }
-
- opcode = pDCLCommand->opcode & ~kFWDCLOpFlagMask;
- if ((opcode == kDCLSendPacketStartOp) || (opcode == kDCLSendPacketOp))
- *pUpdateDCLListEntry++ = pDCLCommand;
- }
-
- // Save update list.
- if (status == noErr)
- {
- pFWAVCPlayBufferGroupData->bufferGroupUpdateDCLList = updateDCLList;
- pFWAVCPlayBufferGroupData->updateListSize = updateListSize;
- }
- else
- {
- pFWAVCPlayBufferGroupData->bufferGroupUpdateDCLList = nil;
- pFWAVCPlayBufferGroupData->updateListSize = 0;
- }
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCAllocateDCLCommand
- //
- // This routine allocates a DCL command.
- //
-
- static DCLCommandPtr FWAVCAllocateDCLCommand(
- DCLCommandPoolPtr pDCLCommandPool,
- UInt32 dclSize)
- {
- DCLCommandBlockPtr pDCLCommandBlock;
- DCLCommandPtr pDCLCommand;
-
- // Get last DCL command block in pool.
- pDCLCommandBlock = pDCLCommandPool->pLastDCLCommandBlock;
-
- // Check if we have enough room in command block. Allocate a new block if there
- // is not enough room.
- if (pDCLCommandBlock != nil)
- {
- if (dclSize > (kDCLCommandPoolBlockSize - pDCLCommandBlock->blockLevel))
- pDCLCommandBlock = FWAVCAllocateDCLCommandBlock (pDCLCommandPool);
- }
- else
- {
- pDCLCommandBlock = FWAVCAllocateDCLCommandBlock (pDCLCommandPool);
- }
-
- // Allocate a DCL from the command block.
- if (pDCLCommandBlock != nil)
- {
- pDCLCommand =
- (DCLCommandPtr) (pDCLCommandBlock->block + pDCLCommandBlock->blockLevel);
- pDCLCommandBlock->blockLevel += dclSize;
- }
- else
- {
- pDCLCommand = nil;
- }
-
- return (pDCLCommand);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCAllocateDCLCommandBlock
- //
- // This routine allocates a DCL command block.
- //
-
- static DCLCommandBlockPtr FWAVCAllocateDCLCommandBlock(
- DCLCommandPoolPtr pDCLCommandPool)
- {
- DCLCommandBlockPtr pDCLCommandBlock = nil;
- Ptr block;
- OSStatus status = noErr;
-
- // Allocate command block record.
- pDCLCommandBlock =
- (DCLCommandBlockPtr) PoolAllocateResident (sizeof (DCLCommandBlock), true);
- if (pDCLCommandBlock == nil)
- status = memFullErr;
-
- // Allocate command block block.
- if (status == noErr)
- {
- block = PoolAllocateResident (kDCLCommandPoolBlockSize, false);
- if (block != nil)
- pDCLCommandBlock->block = block;
- else
- status = memFullErr;
- }
-
- // Insert command block into pool.
- if (status == noErr)
- {
- if (pDCLCommandPool->pFirstDCLCommandBlock != nil)
- pDCLCommandPool->pLastDCLCommandBlock->pNextDCLCommandBlock = pDCLCommandBlock;
- else
- pDCLCommandPool->pFirstDCLCommandBlock = pDCLCommandBlock;
-
- pDCLCommandPool->pLastDCLCommandBlock = pDCLCommandBlock;
- pDCLCommandBlock->pNextDCLCommandBlock = nil;
- }
-
- // Clean up on error.
- if ((status != noErr) && (pDCLCommandBlock != nil))
- {
- FWAVCDeallocateDCLCommandBlock (pDCLCommandBlock);
- pDCLCommandBlock = nil;
- }
-
- // Return results.
- return (pDCLCommandBlock);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCDeallocateDCLCommandBlock
- //
- // This routine deallocates a DCL command block.
- //
-
- static void FWAVCDeallocateDCLCommandBlock(
- DCLCommandBlockPtr pDCLCommandBlock)
- {
- if (pDCLCommandBlock != nil)
- {
- // Deallocate command block block.
- if (pDCLCommandBlock->block != nil)
- PoolDeallocate (pDCLCommandBlock->block);
-
- // Deallocate command block record.
- PoolDeallocate ((Ptr) pDCLCommandBlock);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCAllocateDCLCommandPool
- //
- // This routine allocates a DCL command pool.
- //
-
- static DCLCommandPoolPtr FWAVCAllocateDCLCommandPool(void)
- {
- DCLCommandPoolPtr pDCLCommandPool;
-
- // Allocate DCL command pool record.
- pDCLCommandPool =
- (DCLCommandPoolPtr) PoolAllocateResident (sizeof (DCLCommandPool), true);
-
- return (pDCLCommandPool);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCDeallocateDCLCommandPool
- //
- // This routine deallocates a DCL command pool.
- //
-
- static void FWAVCDeallocateDCLCommandPool(
- DCLCommandPoolPtr pDCLCommandPool)
- {
- DCLCommandBlockPtr pDCLCommandBlock,
- pNextDCLCommandBlock;
-
- if (pDCLCommandPool != nil)
- {
- // Deallocate all command blocks.
- pDCLCommandBlock = pDCLCommandPool->pFirstDCLCommandBlock;
- while (pDCLCommandBlock != nil)
- {
- pNextDCLCommandBlock = pDCLCommandBlock->pNextDCLCommandBlock;
- FWAVCDeallocateDCLCommandBlock (pDCLCommandBlock);
- pDCLCommandBlock = pNextDCLCommandBlock;
- }
-
- // Deallocate command pool record.
- PoolDeallocate ((Ptr) pDCLCommandPool);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCAddCycleTimeToCycleTime
- //
- // This routine adds the two given cycle times.
- //
-
- static UInt32 FWAVCAddCycleTimeToCycleTime(
- UInt32 cycleTime1,
- UInt32 cycleTime2)
- {
- UInt32 secondCount,
- cycleCount,
- cycleOffset;
- UInt32 cycleTime;
-
- // Add cycle offsets.
- cycleOffset = (cycleTime1 & 0x0FFF) + (cycleTime2 & 0x0FFF);
-
- // Add cycle counts.
- cycleCount = (cycleTime1 & 0x01FFF000) + (cycleTime2 & 0x01FFF000);
-
- // Add any carry over from cycle offset to cycle count.
- if (cycleOffset > 3071)
- {
- cycleCount += 0x1000;
- cycleOffset -= 3072;
- }
-
- // Add secondCounts.
- secondCount = (cycleTime1 & 0xE0000000) + (cycleTime2 & 0xE0000000);
-
- // Add any carry over from cycle count to secondCount.
- if (cycleCount > (8000 << 12))
- {
- secondCount += 0x20000000;
- cycleCount -= (8000 << 12);
- }
-
- // Put everything together into cycle time.
- cycleTime = secondCount | cycleCount | cycleOffset;
-
- return (cycleTime);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCSubtractCycleTimeFromCycleTime
- //
- // This routine subtracts the two given cycle times.
- //
-
- static UInt32 FWAVCSubtractCycleTimeFromCycleTime(
- UInt32 cycleTime1,
- UInt32 cycleTime2)
- {
- SInt32 secondCount,
- cycleCount,
- cycleOffset;
- UInt32 cycleTime;
-
- // Subtract cycle offsets.
- cycleOffset = (cycleTime1 & 0x0FFF) - (cycleTime2 & 0x0FFF);
-
- // Subtract cycle counts.
- cycleCount = (cycleTime1 & 0x01FFF000) - (cycleTime2 & 0x01FFF000);
-
- // Subtract any borrow over from cycle offset to cycle count.
-
- if (cycleOffset < 0)
- {
- cycleCount -= 0x1000;
- cycleOffset += 3072;
- }
-
- // Subtract secondCounts.
- secondCount = (cycleTime1 & 0xE0000000) - (cycleTime2 & 0xE0000000);
-
- // Subtract any borrow over from cycle count to secondCount.
- if (cycleCount < 0)
- {
- secondCount -= 0x20000000;
- cycleCount += (8000 << 12);
- }
-
- // Put everything together into cycle time.
- cycleTime = secondCount | cycleCount | cycleOffset;
-
- return (cycleTime);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWAVCConvertFractionalSecondsToCycleTime
- //
- // This routine converts a time represented in fractional seconds to a time
- // represented in cycle timer format.
- //
-
- static UInt32 FWAVCConvertFractionalSecondsToCycleTime(
- UInt32 secondsNumerator,
- UInt32 secondsDenominator)
- {
- float fSecondCount;
- float fCycleCount;
- float fCycleOffset;
- UInt32 iSecondsCount;
- UInt32 iCycleCount;
- UInt32 iCycleOffset;
- UInt32 secondsCycleTime;
-
- // Convert fractional seconds into floating point and compute seconds count.
- fSecondCount = ((float) secondsNumerator) / ((float) secondsDenominator);
- iSecondsCount = (UInt32) fSecondCount;
-
- // Subtract whole seconds out of fSecondCount and convert to cycle count.
- fCycleCount = (fSecondCount - ((float) iSecondsCount)) * 8000.0;
- iCycleCount = (UInt32) fCycleCount;
-
- // Subtract whole cycles out of fCycleCount and convert to cycle offset.
- fCycleOffset = (fCycleCount - ((float) iCycleCount)) * 3072.0;
- iCycleOffset = (UInt32) fCycleOffset;
-
- // Convert to cycle timer format.
- secondsCycleTime = (iSecondsCount << 25) | (iCycleCount << 12) | iCycleOffset;
-
- return (secondsCycleTime);
- }
-